package com.ruge.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.entity.UrlEncodedFormEntity;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.NameValuePair;
import org.apache.hc.core5.http.ParseException;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.message.BasicNameValuePair;
import org.apache.hc.core5.util.Timeout;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 基于HttpClient 5.5和FastJSON的HTTP工具类
 * 修复超时配置方法，使用正确的API
 */
public class HTTPUtil {

    // 超时时间设置(单位：秒)
    private static final int TIMEOUT_SECONDS = 30;
    // 超时时间对象
    private static final Timeout TIMEOUT = Timeout.ofSeconds(TIMEOUT_SECONDS);
    // Unicode正则表达式
    private static final Pattern UNICODE_PATTERN = Pattern.compile("\\\\u([0-9a-fA-F]{4})");

    /**
     * 发送GET请求，返回字符串结果(自动转换Unicode为中文)
     */
    public static String doGet(String url) {
        String response = executeGetRequest(url);
        return convertUnicodeToChinese(response);
    }

    /**
     * 发送GET请求，返回JSONObject(自动转换Unicode为中文)
     */
    public static JSONObject doGetAsJson(String url) {
        String response = executeGetRequest(url);
        return parseToJson(convertUnicodeToChinese(response));
    }

    /**
     * 发送POST请求，返回字符串结果(自动转换Unicode为中文)
     */
    public static String doPost(String url, Map<String, String> params) {
        String response = executePostRequest(url, params);
        return convertUnicodeToChinese(response);
    }

    /**
     * 发送POST请求，返回JSONObject(自动转换Unicode为中文)
     */
    public static JSONObject doPostAsJson(String url, Map<String, String> params) {
        String response = executePostRequest(url, params);
        return parseToJson(convertUnicodeToChinese(response));
    }

    /**
     * 发送JSON格式的POST请求(自动转换Unicode为中文)
     */
    public static String doPostJson(String url, String json) {
        String response = executePostJsonRequest(url, json);
        return convertUnicodeToChinese(response);
    }

    /**
     * 发送JSON格式的POST请求，返回JSONObject(自动转换Unicode为中文)
     */
    public static JSONObject doPostJsonAsJson(String url, String json) {
        String response = executePostJsonRequest(url, json);
        return parseToJson(convertUnicodeToChinese(response));
    }

    /**
     * 执行GET请求的实际实现 - 使用正确的超时配置方法
     */
    private static String executeGetRequest(String url) {
        // 创建请求配置构建器（使用HttpClient 5.5正确的超时配置方法）
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(TIMEOUT)             // 连接超时
                .setResponseTimeout(TIMEOUT)            // 响应超时
                .setConnectionRequestTimeout(TIMEOUT)   // 连接请求超时
                .build();

        try {
            CloseableHttpClient httpClient = HttpClientBuilder.create()
                    .disableContentCompression()
                    .disableRedirectHandling()
                    .setConnectionManager(new PoolingHttpClientConnectionManager())
                    .build();

            HttpGet httpGet = new HttpGet(url);
            
            // 设置超时配置
            httpGet.setConfig(requestConfig);
            
            // 执行请求
            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    return EntityUtils.toString(entity, StandardCharsets.UTF_8);
                }
            }
        } catch (IOException | ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 执行POST请求的实际实现 - 使用正确的超时配置方法
     */
    private static String executePostRequest(String url, Map<String, String> params) {
        // 创建请求配置构建器
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(TIMEOUT)             // 连接超时
                .setResponseTimeout(TIMEOUT)            // 响应超时
                .setConnectionRequestTimeout(TIMEOUT)   // 连接请求超时
                .build();

        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(url);
            
            // 设置请求头
            if (false) {
                httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
            } else {
                httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
            }
            
            // 设置超时配置
            httpPost.setConfig(requestConfig);
            
            // 设置表单参数
            if (params != null && !params.isEmpty()) {
                List<NameValuePair> nameValuePairs = new ArrayList<>();
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    nameValuePairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
                }
                httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, StandardCharsets.UTF_8));
            }
            
            // 执行请求
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    return EntityUtils.toString(entity, StandardCharsets.UTF_8);
                }
            }
        } catch (IOException | ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 执行JSON格式POST请求的实际实现
     */
    private static String executePostJsonRequest(String url, String json) {
        // 创建请求配置构建器
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(TIMEOUT)             // 连接超时
                .setResponseTimeout(TIMEOUT)            // 响应超时
                .setConnectionRequestTimeout(TIMEOUT)   // 连接请求超时
                .build();

        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(url);
            
            // 设置JSON请求头
            httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
            
            // 设置超时配置
            httpPost.setConfig(requestConfig);
            
            // 设置JSON请求体
            if (json != null && !json.isEmpty()) {
                httpPost.setEntity(new org.apache.hc.core5.http.io.entity.StringEntity(json, StandardCharsets.UTF_8));
            }
            
            // 执行请求
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    return EntityUtils.toString(entity, StandardCharsets.UTF_8);
                }
            }
        } catch (IOException | ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 使用FastJSON将字符串解析为JSONObject
     */
    private static JSONObject parseToJson(String response) {
        if (response == null || response.isEmpty()) {
            return null;
        }
        try {
            return JSON.parseObject(response);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将Unicode编码转换为中文
     */
    private static String convertUnicodeToChinese(String unicodeStr) {
        if (unicodeStr == null || unicodeStr.isEmpty()) {
            return unicodeStr;
        }
        
        Matcher matcher = UNICODE_PATTERN.matcher(unicodeStr);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            String hex = matcher.group(1);
            int code = Integer.parseInt(hex, 16);
            matcher.appendReplacement(sb, new String(Character.toChars(code)));
        }
        matcher.appendTail(sb);
        return sb.toString();
    }
}
    